<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<p>1</p>
<p>2</p>
<p>3</p>
<script>
    /*
    * 解构赋值：解析某一数据的结构，将我们想要的内容提取出来，赋值给变量或者常量的es6的一种赋值方式
    *
    * 解构赋值形式：[变量,变量,变量...] = [值,值,值...] 或者 {变量,变量,变量...} = {值,值,值...}
    *
    * 假设我们有一个数组，要用变量或者常量对其中每一项进行赋值保存，原来的做法是这样：
    * const arr = [1,2,3]
    * const a = arr[0]
    * const b = arr[1]
    * const c = arr[3]
    * console.log(a,b,c) //打印出 1，2，3
    *
    * 如果使用解构赋值则是这样：
    * const arr1 = [4,5,6]
    * const [d,e,f] = arr1
    * console.log(d,e,f) //打印出 4，5，6
    *
    * 也可以直接赋值：
    * const [a,b,c] = [1,2,3]
    * console.log(a,b,c) //打印出1，2，3
    *
    *
    * */

    /*
    * 数组的解构赋值：
    *   数组解构赋值的原理：
    *   1.模式或者结构相匹配
    *   2.索引值相同的完成赋值
    *
    *   模式或结构相匹配
    *   let arr = [1,2,3] //必须是数组对数组，等号左边是数组，等号右边也是数组
    *
    *   索引值相同的完成赋值
    *   let [a,b,c] = [1,2,3] //a的索引值为0,1的索引值也为0,1赋值给a，b索引值为1,2索引值也为1,2赋值给b，以此类推
    *
    *   假设有一个数组[a,b,c,d]，我们要对其中每一项进行赋值
    *   let [a,b,c,d] = [1,2,[3,4],5]
    *   console.log(a,b,c,d) //打印1，2，[3,4]，5，其中a=1，b=2，c=[3,4]，d=5
    *
    *   如果只想取到第三项中的数字4，可以这样取：
    *   let [,,[,a]] = [1,2,[3,4],5] //即不想取到的数值可以用逗号进行跳过
    *   console.log(a)
    *
    *   又比如我们只想取第二项数字2，第三项中的第二项数字4，第五项数字6
    *   let [,b,[,c],,d] = [1,2,[3,4],5,6] //还是不想取到的直接用逗号跳过
    *   console.log(b,c,d)
    *
    *   以上取值都要注意模式与结构的相匹配，索引值相同的完成赋值
    *
    * */

    /*
    * 数组解构赋值的默认值：
    *
    * 1.默认值的基本用法
    *   const [a,b,c] = [] //什么都没赋值，相当于赋值了undefined
    *   console.log(a,b,c) //打印undefined，undefined，undefined
    *   第一句代码就相当于
    *   const [a,b,c] = [undefined,undefined,undefined]
    *
    *   但是我们不希望没赋值的时候赋值为undefined，就可以这样：
    *   const [d = 1,e = 2,f = 3] = []
    *   console.log(d,e,f) //打印1,2,3
    *   这里等号左边 const [d = 1,e = 2,f = 3] 就是在给数组每一项添加默认值，而默认值的生效条件，
    *   必须是等号右边什么都没赋值即为空数组的情况[]，或者是严格等于undefined，即[undefined,undefined,undefined]
    *
    *   只有赋值为空或者明显赋值为undefined的数组项，才会取默认值：
    *   let [a = 1,b = 2,c = 3] = []
    *   let [d = 4,e = 5,f = 6] = [undefined,undefined,undefined]
    *   let [g = 7,h = 8,i = 9] = [666,,undefined]
    *
    *   console.log(a,b,c,d,e,f,g,h,i) //打印1 2 3 4 5 6 666 8 9，因为g明显赋值了666，既不是空也不是undefined
    *
    *
    * */

    /*
    * 如果默认值是一个表达式，那么默认值表达式是惰性求值的：
    *   let fn = () => {
    *       console.log("fn被执行了")
    *       return 666
    *   }
    *
    *   //当变量x即被赋值了默认值表达式又被明显赋值了非空或者非undefined时，变量x优先取该值，不会取默认值表达式的值
    *   let [x = fn()] = [1] //此时变量x取等号右边的值1
    *   console.log(x) //打印1
    *
    *   //如果变量x,y只被赋值了默认值表达式，等号右边是空或者是undefined，则取默认值表达式执行之后的值
    *   let [x = fn()] = [] //此时变量x取等号左边的默认值表达式fn的执行结果
    *   let [y = fn()] = [undefined] //此时变量y取等号左边的默认值表达式fn的执行结果
    *   console.log(x,y) //打印的x y都是 fn被执行了 666
    *
    *
    * */

    /*
    * 数组结构赋值的应用：
    *   1.类数组arguments
    *   function fn(){
    *       const [a = 4,b = 5,c = 6] = arguments //arguments接收了传入的实参1,2,3，通过结构赋值的形式赋值给了a，b，c
    *       //即是这一步 const [a,b,c] = [1,2,3]
    *       console.log(a,b,c)
    *   }
    *   fn(1,2,3) //这里明显传了实参
    *   fn() //这里不传实参，则会取解构赋值的默认值a = 4,b = 5,c = 6
    *
    *   2.类数组NodeList
    *   let p = document.querySelectorAll("p") //获取三个p标签
    *   const [p1,p2,p3] = p //把获取到的三个p标签分别赋值给三个常量p
    *   console.log(p1) //打印 <p>1<p>
    *   console.log(p2) //打印 <p>2<p>
    *   console.log(p3) //打印 <p>3<p>
    *   p1.style.color = "green"
    *
    * */

    /*
    * 函数参数的解构赋值的应用：
    *
    * 原本我们给函数传参是这样：
    *   let array = [10,20]
    *   const add = (arr) => arr[0] + arr[1]
    *   console.log(add(array))
    *
    * 但是我们可以用解构赋值传参
    *   let array1 = [30,40]
    *   const add1 = ([x,y]) => x + y //这行代码结合下一行代码一起看，函数add1接收的形参变量 ([x,y])
    *   console.log(add1(array1)) //这行代码结合上一行代码一起看，函数add1传入值 array1
    *   //其实就是解构赋值 ([x,y]) = array1，即([x,y]) = [30,40]
    *
    * 但是上面的代码还不够完美，如果用户在add1()中传入一个空数组或者传入参数不齐，就会出现NaN，所以还需要给解构赋值添加默认值
    *   let array1 = [30,40]
    *   const add1 = ([x=0,y=0]) => x + y
    *   //这里就给解构赋值添加了默认值0，不传参数或者参数不齐的就是undefined，出现undefined的变量就会使用设置的默认值
    *   console.log(add1([])) //传入一个空，则是0+0返回一个0
    *   console.log(add1([2])) //传入一个2，则x=2，y是undefined就取默认值0,2+0，返回2
    *
    * */

    /*
    * 交换变量的值：
    *   原来的交换方法：用中间值
    *   let a = 10
    *   let b = 20
    *
    *   let temp = a
    *   a = b
    *   b = temp
    *   console.log(a,b) //就交换好了
    *
    *   使用解构赋值：
    *   let c = 30
    *   let d = 40
    *   [c,d] = [d,c]
    *   //就交换好了 等号右边是变量[c,d]，等号左边是变量d，变量c所对应的值[40,30]，[c,d] = [40,30]
    *
    *
    * */



</script>
</body>
</html>